/**
 * 根据从爬虫处获得的数据，打包app，或者启动指定的workflow
 */

var fs = require("fs");
var path = require("path");
var repl = require("repl");

var nodeJsZip = require("nodeJs-zip");

var Spider = require("../Spider/index");

var config = require("./path.json");

var zips = path.join(__dirname,"./zips");

var task = (function(){
    var spider = new Spider("172.6.2.54","8080");
    var appRoot = "";
    var appBundlePath = "";
    var thingsPath = "";

    var pack = function * (){
        yield packApps();
        yield packThings();

        var jsonData = {
            root : appRoot,
            appBundle : appBundlePath,
            things : thingsPath
        };
        fs.writeFileSync(path.join(__dirname,"path.json"),JSON.stringify(jsonData));
    };

    var packApps = function * (name){
        var apps = yield spider.getAppsData();
        var paths = [];

        var app = apps.length ? apps[0].path : "";
        var re = /(.*)\/node_modules\//i;
        appRoot = re.exec(app);

        if(! appRoot) throw new Error("must have at least one app");

        appRoot = appRoot[1];

        appBundlePath = path.join(appRoot,"./node_modules/hope-demo/center/appbundle");

        if(name){
            for(app of apps){
                if(app.name === name){
                    nodeJsZip.zip(app.path,{
                        name : "name",
                        dir : zips
                    });        // 压缩一个
                }
            }
        }else{
            for(app of apps){
                paths.push(app.path);
            }
            nodeJsZip.zip(paths,{
                name : "appbundles",
                dir : zips
            });       // 压缩一堆
        }
    };

    var packThings = function * (){
        var things = yield spider.getThingsData();
        var thing;
        var re = /(.*(hope-demo)\/\w*)/i;
        var paths = [];
        for(thing of things){
            var result = re.exec(thing);
            if(result && paths.indexOf(result[0]) === -1){
                paths.push(result[0]);
            }
        }
        nodeJsZip.zip(paths,{
            name : "things",
            dir : zips
        });
    };
    
    

    var extraApps = function *(){
        var newPaths = yield spider.getBundlePath();        // new app's paths
        var appBundleZip = path.join(zips,"appbundles.zip");
        var thingsZip = path.join(zips,"things.zip");

        var processApp = function(isDir,name,data){        // unzip apps
            var p = path.join(newPaths.appPath,name);
            if(isDir){

                if(! fs.existsSync(p)){
                    fs.mkdirSync(p);
                }

            }else if(!isDir){

                fs.writeFileSync(p,data);

            }
        };
        nodeJsZip.unzip(appBundleZip,processApp);

        var processThings = function(isDir,name,data){     // unzip things and replace all files
            var p = path.join(newPaths.thingsPath,name);
            if(isDir){

                if(! fs.existsSync(p)){
                    fs.mkdirSync(p);
                }

            }else if(!isDir){

                fs.writeFileSync(p,data);

            }
        };
        nodeJsZip.unzip(thingsZip,processThings);
    };

    var getGraphId = function * (appName,workflowName) {
        workflowName = workflowName || "Default Workflow";

        var apps = yield spider.getAppsData();
        var app;
        for(var a of apps){
            if(a.name === appName){
                app = a;
                break;
            }
        }

        if(! app) return false;

        var graphs = app.graphs;
        var graph;
        for(var g of graphs){
            if(g.name === workflowName){
                graph = g;
                break;
            }
        }

        if(! graph) return false;

        return graph.id;
    };

    /**
     * startWorkflow of given appName and workflowName
     * @param appName
     * @param workflowName
     * @return 200  ok
     * @return 500  workflow is running
     */
    var startWorkflow = function * (appName,workflowName){

        var id = yield getGraphId(appName,workflowName);
        if(! id) return false;

        return yield spider.startWorkflow(id);
    };

    /**
     * stopWorkflow of given appName and workflowName
     * @param appName
     * @param workflowName
     * @return 200 ok
     * @return 500 workflow is not running
     */
    var stopWorkflow = function * (appName,workflowName) {

        var id = yield getGraphId(appName,workflowName);
        if(! id) return false;

        return yield spider.stopWorkflow(id);
    };

    return {
        spider : spider,
        pack : pack,
        packApps : packApps,
        packThings : packThings,
        extraApps: extraApps,
        startWorkflow : startWorkflow,
        stopWorkflow : stopWorkflow
    }
}());
module.exports = task;